#include "osLib.h"

//  为简化代码编写添加的宏
#define firstNode       headNode.nextNode
#define lastNode        headNode.preNode

/*****************************************************************************
 * @function        vNodeInit
 * @brief 			链表节点初始化.
 *  
 * @param[in] 		node 要初始化的链表节点.
 * 
 * @return 			None.	
 *
 * ***************************************************************************/
void        vNodeInit(NODE_T *node)
{
    node->nextNode = node;
    node->preNode = node;
}

/*****************************************************************************
 * @function        vListInit
 * @brief 			链表初始化. 将链表的头节点的前后节点指向头节点，并将节点数
 *              置为0.
 *  
 * @param[in] 		list 要初始化的链表.
 * 
 * @return 			None.	
 *
 * ***************************************************************************/
void        vListInit(LIST_T *list)
{
    list->firstNode = &(list->headNode);
    list->lastNode = &(list->headNode);
    
    list->nodeCount = 0;
}


/*****************************************************************************
 * @function        vListCount
 * @brief 			计算当前链表的节点个数.
 * 
 * @return 			返回当前链表的节点数.	
 *
 * ***************************************************************************/
uint32_t    vListCount(LIST_T *list)
{
    return list->nodeCount;
}


/*****************************************************************************
 * @function        vListFirst
 * @brief 			获取当前链表的首个节点.
 *  
 * @param[in] 		list 指向当前链表的指针.
 * 
 * @return 			返回当前链表的首个节点   
 *
 * ***************************************************************************/
NODE_T*     vListFirst(LIST_T *list)
{
    NODE_T *node = (NODE_T *) 0;
    
    if (list->nodeCount)
    {
        node = list->firstNode;
    }
    return node;
}

/*****************************************************************************
 * @function        vListLast
 * @brief 			获取当前链表的最后一个节点.
 *  
 * @param[in] 		list 指向当前链表的指针.
 * 
 * @return 			返回当前链表的最后一个节点.  
 *
 * ***************************************************************************/
NODE_T*     vListLast(LIST_T *list)
{
    NODE_T *node = (NODE_T *) 0;
    
    if (list->nodeCount)
    {
        node = list->lastNode;
    }
    return node;
}

/*****************************************************************************
 * @function        vListLast
 * @brief 			获取当前链表指定节点的下一个节点.
 *  
 * @param[in] 		list 指向当前链表的指针.
 * @param[in] 		node 指定节点的指针.
 * 
* @return 			返回当前链表指定节点的下一个节点.若当前节点没有前节点（链表为空），则返回NULL
 *
 * ***************************************************************************/
NODE_T*     vListNext(LIST_T *list, NODE_T *node)
{
    if (node->nextNode == node)
    {
        return (NODE_T *)0;
    }
    else {
        return node->nextNode;
    }
}

/*****************************************************************************
 * @function        vListLast
 * @brief 			获取当前链表指定节点的上一个节点.
 *  
 * @param[in] 		list 指向当前链表的指针.
 * @param[in] 		node 指定节点的指针.
 * 
* @return 			返回当前链表指定节点的上一个节点.若当前节点没有前节点（链表为空），则返回NULL
 *
 * ***************************************************************************/
NODE_T*     vListPre(LIST_T *list, NODE_T *node)
{
    if (node->preNode == node)
    {
        return (NODE_T *)0;
    }
    else {
        return node->preNode;
    }
}

/*****************************************************************************
 * @function        vListRemoveAll
 * @brief 			清除当前链表中的所有节点.
 *  
 * @param[in] 		list 要清除节点的链表.
 * 
 * @return 			None.	
 *
 * ***************************************************************************/
void        vListRemoveAll(LIST_T *list)
{
    NODE_T *curNode;
    NODE_T *nextNode;
    
    curNode = list->firstNode;
    while (list->nodeCount)
    {
        /* 先记录下一个节点的位置*/
        nextNode = curNode->nextNode;
        
        /* 清除当前节点信息---清除效果：当前节点的前后节点指向自己*/
        curNode->nextNode = curNode;
        curNode->preNode = curNode;
        
        /* 更新当前节点*/
        curNode = nextNode;
        /* 更新链表节点数*/
        list->nodeCount--;
    }

    /* 更新链表的头节点*/
    list->firstNode = &(list->headNode);
    list->lastNode = &(list->headNode);
}

/*****************************************************************************
 * @function        vListAddFirst
 * @brief 			在链表头添加一个节点.
 *  
 * @param[in] 		list 待添加的链表.
 * @param[in]       node 待添加的节点.
 * 
 * @return 			None.	
 *
 * ***************************************************************************/
void        vListAddFirst(LIST_T *list, NODE_T *node)
{
    node->nextNode = list->firstNode;
    node->preNode = list->firstNode->preNode;
    
    list->firstNode->preNode = node;
    list->firstNode = node;
    list->nodeCount++;
}

/*****************************************************************************
 * @function        vListAddFirst
 * @brief 			在链表尾部添加一个节点.
 *  
 * @param[in] 		list 待添加的链表.
 * @param[in]       node 待添加的节点.
 * 
 * @return 			None.	
 *
 * ***************************************************************************/
void        vListAddLast(LIST_T *list, NODE_T *node)
{
    node->nextNode = list->lastNode->nextNode;
    node->preNode = list->lastNode;
    
    list->lastNode->nextNode = node;
    list->lastNode = node;
    list->nodeCount++;
}


/*****************************************************************************
 * @function        vListRemoveFirst
 * @brief 			删除链表首个节点。
 *  
 * @param[in] 		list 待删除节点的链表
 * 
 * @return 			被删除的节点.	
 *
 * ***************************************************************************/
NODE_T*     vListRemoveFirst(LIST_T *list)
{
    NODE_T *node = (NODE_T *)0;
    
    if (list->nodeCount)
    {
        /* 获取要被删除的节点*/
        node = list->firstNode;
        
        /* 将链表头和删除节点的下一个节点进行联系*/
        list->firstNode = node->nextNode;
        node->nextNode->preNode = node->preNode;
        
//        /* 将被删除的节点前后信息清除*/
//        node->nextNode = node;
//        node->preNode = node;
        
        /* 更新链表的节点数*/
        list->nodeCount--;
    }   
    
    return node;
}

/*****************************************************************************
 * @function        vListRemoveLast
 * @brief 			删除链表尾部节点。
 *  
 * @param[in] 		list 待删除节点的链表
 * 
 * @return 			被删除的节点.	
 *
 * ***************************************************************************/
NODE_T*     vListRemoveLast(LIST_T *list)
{
    NODE_T *node = (NODE_T *)0;
    
    if (list->nodeCount)
    {
        /* 获取要被删除的节点*/
        node = list->lastNode;
        
        /* 将链表头和删除节点的下一个节点进行联系*/
        list->lastNode = node->preNode;
        node->preNode->nextNode = node->nextNode;
        
//        /* 将被删除的节点前后信息清除*/
//        node->nextNode = node;
//        node->preNode = node;
        
        /* 更新链表的节点数*/
        list->nodeCount--;
    }   
    
    return node;
}

/*****************************************************************************
 * @function        vListInsterAfter
 * @brief 			在链表的指定节点后面添加一个节点.
 *  
 * @param[in] 		list 待添加节点的链表.
 * @param[in]       node 参考节点.
 * @param[in] 	    nodeToInsert 要插入的节点.
 * 
 * @return 			None.	
 * @node            注意，该函数未判断参考节点是否属于当前链表，使用时需要注意！！！
 *
 * ***************************************************************************/
void        vListInsterAfter(LIST_T *list, NODE_T *node, NODE_T *nodeToInsert)
{
    /* 未判断参考节点是否在当前链表中*/
    
    nodeToInsert->nextNode = node->nextNode;
    nodeToInsert->preNode = node;
    
    node->nextNode->preNode = nodeToInsert;
    node->nextNode = nodeToInsert;
    
    list->nodeCount++;
}


/*****************************************************************************
 * @function        vListInsterAfter
 * @brief 			删除链表中指定节点.
 *  
 * @param[in] 		list 待删除节点的链表.
 * @param[in] 	    nodeToInsert 要删除的节点.
 * 
 * @return          none
 * @node            注意：该函数未检测node是否属于当前list，使用时需要特别注意！！
 *
 * ***************************************************************************/
void vListRemove(LIST_T *list, NODE_T *node)
{
    node->nextNode->preNode = node->preNode;
    node->preNode->nextNode = node->nextNode;
        
    list->nodeCount--;
}

